#include <arch.h>
#include <context.h>
#include <conio.h>
#include <cpu.h>
#include <pic.h>
#include <paging.h>
#include <schedule.h>
#include <timer.h>
#include <irq.h>
/* from up layer */
#include <sys/intr.h>	/* up level irq dispatch proc */
#include <sys/thread.h>
#include <sys/unistd.h>
/* from sys/thread.h! */
extern thread_t *curth;

/* main irq handler */
uint32_t int_handler(uint32_t irqn, userframe_t *stack0)
{
    context_t *ctx = NULL;
    
    sched_lock();

    gotoxy(0, 0);
    setcolor(12);
    kprintf("irq: %d, curth uptime: %d", irqn, curth->run_time);
    setcolor(0x02);
    
    mask_irq(irqn);	/* masking irq */

    if (irqn == 0)	/* timer ISR */
	ctx=schedule();

	 //   irq_run(irqn);	/* from up level */
    send_eoirq(irqn);
    unmask_irq(irqn);
    
    if (!ctx)
   	ctx = &curth->ctx;

    sched_unlock();

    return ((uint32_t)ctx);
}

void irq_init()
{
    kprintf("install default interrupt handlers...");

    add_idtirq((uint32_t *) idt, 0x20, SEL_KCODE, int00_handler);
    add_idtirq((uint32_t *) idt, 0x21, SEL_KCODE, int01_handler);
    add_idtirq((uint32_t *) idt, 0x22, SEL_KCODE, int02_handler);
    add_idtirq((uint32_t *) idt, 0x23, SEL_KCODE, int03_handler);
    add_idtirq((uint32_t *) idt, 0x24, SEL_KCODE, int04_handler);
    add_idtirq((uint32_t *) idt, 0x25, SEL_KCODE, int05_handler);
    add_idtirq((uint32_t *) idt, 0x26, SEL_KCODE, int06_handler);
    add_idtirq((uint32_t *) idt, 0x27, SEL_KCODE, int07_handler);
    add_idtirq((uint32_t *) idt, 0x28, SEL_KCODE, int08_handler);
    add_idtirq((uint32_t *) idt, 0x29, SEL_KCODE, int09_handler);
    add_idtirq((uint32_t *) idt, 0x2a, SEL_KCODE, int0a_handler);
    add_idtirq((uint32_t *) idt, 0x2b, SEL_KCODE, int0b_handler);
    add_idtirq((uint32_t *) idt, 0x2c, SEL_KCODE, int0c_handler);
    add_idtirq((uint32_t *) idt, 0x2e, SEL_KCODE, int0d_handler);
    add_idtirq((uint32_t *) idt, 0x2f, SEL_KCODE, int0e_handler);
    add_idtirq((uint32_t *) idt, 0x30, SEL_KCODE, int0f_handler);
    /* syscalls entry */
    add_idtuirq((uint32_t * ) idt, 0x80, SEL_KCODE, syscall_entry);
    
    unmask_irq(0);		/* timer irq */
    unmask_irq(2);		/* for cascading PICs */
    unmask_irq(9);
    kprintf("Ok.\n");
}
